package org.fuyd.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Hex;

public class RSASign {
  public static void jdkRSA(String src) {
    try {
      /** 1、初始化密钥 **/
      // 创建一个RSA算法的KeyPairGenerator对象（密钥对生成器）
      KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
      // 初始化KeyPairGenerator的密钥大小
      keyPairGenerator.initialize(512);
      // 生成密钥对
      KeyPair keyPair = keyPairGenerator.generateKeyPair();
      // 获取公钥
      RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
      // 获取私钥
      RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();

      /** 2、执行签名 **/
      // 创建一个PKCS8EncodedKeySpec对象
      PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
      // 创建一个RSA算法的KeyFactory对象
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      // 创建一个私钥
      PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
      // 创建一个MD5withRSA算法的Signature对象
      Signature signature = Signature.getInstance("MD5withRSA");
      // 初始化Signature对象
      signature.initSign(privateKey);
      // 更新该Signature对象
      signature.update(src.getBytes("UTF-8"));
      // 签名
      byte[] b = signature.sign();
      System.out.println("JDK RSA Sign: " + Hex.encodeHexString(b));

      /** 3、验签名 **/
      X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
      PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
      signature = Signature.getInstance("MD5withRSA");
      signature.initVerify(publicKey);
      signature.update(src.getBytes("UTF-8"));
      boolean ba = signature.verify(b);
      System.out.println("JDK RSA Verify: " + ba);

    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (InvalidKeySpecException e) {
      e.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (SignatureException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    jdkRSA("fuyongde");
  }
}
